home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- ** **
- ** Module: SR_PointPipe.c **
- ** **
- ** **
- ** Purpose: Sample Renderer point pipeline **
- ** **
- ** **
- ** **
- ** Copyright (C) 1996 Apple Computer, Inc. All rights reserved. **
- ** **
- ** **
- *****************************************************************************/
- #include <stdlib.h>
- #include <assert.h>
-
- #include "QD3D.h"
- #include "QD3DMath.h"
- #include "QD3DErrors.h"
-
- #include "SR.h"
- #include "SR_ClipUtilities.h"
-
-
- /*===========================================================================*\
- *
- * Routine: SR_PointPipe()
- *
- * Comments: Used for points, and for lines and triangles in point mode.
- *
- \*===========================================================================*/
-
- TQ3Status SR_PointPipe(
- TSRPrivate *srPrivate,
- TQ3Point3D *localVertices,
- long numVertices,
- long sizeOfLocalVertices,
- TQ3ColorRGB *color,
- TQ3Vector3D *normal,
- long mode)
- {
- TQ3Status status;
- unsigned long i;
- TQ3RationalPoint4D *deviceVertices = NULL;
- TQ3RationalPoint4D *clippedVertices = NULL;
- TQ3RationalPoint4D *renderVertices = NULL;
- long clipFound, allOut;
- unsigned long *clipFlags = NULL;
- long *clippedVerticesFlags = NULL;
- PointFunction2D pointFunction;
-
- /*
- * Get the appropriate rasterization function for the points
- * (depth, whether window is clipped or not, etc.
- */
- pointFunction =
- ((TSRRasterFunctions *)(srPrivate->currentRasterFunctions))->pointFunction;
-
- /*
- * If we're in "DO_POLYGON" mode, then we have to consider whether
- * we need to cull or not.
- */
- if (mode == DO_POLYGON) {
- assert(normal != NULL);
-
- /*
- * We will attempt to do culling if the rank of the upper-left 3x3
- * submatrix of the local-to-world matrix is at least 2.
- * A rank of 3 means that volumes are transformed into volumes.
- * A rank of 2 means that volumes are transformed onto a plane.
- * For a rank of 1 (line) or 0 (point), we bypass the culling stage
- * and just render the line or point.
- */
- if (srPrivate->backfacingStyle == kQ3BackfacingStyleRemove &&
- (srPrivate->normalLocalToWorldRank >= 2)) {
-
- if (normal->x * normal->x +
- normal->y * normal->y +
- normal->z * normal->z < 1.e-10) {
- /*
- * Normal vector's length is < 1.e-10 meaning the
- * polygon is degenerate
- */
- return (kQ3Success);
- }
-
- /*
- * If the local-to-world matrix has a rank of 2, then the eye
- * in local coordinates is a vector even if the view is a
- * perspective transformation.
- */
- if ((srPrivate->cameraType == kQ3CameraTypeOrthographic) ||
- (srPrivate->normalLocalToWorldRank == 2)) {
-
- /* Orthographic projection */
- if ((normal->x * srPrivate->eyeVectorInLocalCoords.x +
- normal->y * srPrivate->eyeVectorInLocalCoords.y +
- normal->z * srPrivate->eyeVectorInLocalCoords.z < 0.0) ^
- ((srPrivate->orientationStyle ==
- kQ3OrientationStyleClockwise))) {
- /*
- * Backfacing so cull it
- */
- return (kQ3Success);
- }
- } else {
- TQ3Point3D *point;
- TQ3Vector3D eyeVector;
-
- /* Perspective projection */
- point = localVertices;
- eyeVector.x = srPrivate->eyePointInLocalCoords.x - point->x;
- eyeVector.y = srPrivate->eyePointInLocalCoords.y - point->y;
- eyeVector.z = srPrivate->eyePointInLocalCoords.z - point->z;
- if ((normal->x * eyeVector.x +
- normal->y * eyeVector.y +
- normal->z * eyeVector.z < 0.0) ^
- ((srPrivate->orientationStyle ==
- kQ3OrientationStyleClockwise))) {
- /*
- * Backfacing so cull it
- */
- return (kQ3Success);
- }
- }
- }
- }
-
- status = kQ3Success;
-
- /*
- * Allocate device-coordinate vertices
- */
- deviceVertices = malloc(numVertices * sizeof(TQ3RationalPoint4D));
- if (deviceVertices == NULL) {
- status = kQ3Failure;
- goto bail;
- }
-
- /*
- * Transform local-space point vertices to device space
- */
- Q3Point3D_To4DTransformArray(
- localVertices,
- &srPrivate->transforms.localToDC,
- deviceVertices,
- numVertices,
- sizeOfLocalVertices,
- sizeof(TQ3RationalPoint4D));
-
- /*
- * renderVertices are those that will be rendered. If there is a clip,
- * then we'll set this to the clipped vertices instead.
- */
- renderVertices = deviceVertices;
-
- /*
- * Allocate a clip flag for each vertex. Bail if allocation fails.
- */
- clipFlags = malloc(numVertices * sizeof(unsigned long));
- if (clipFlags == NULL) {
- status = kQ3Failure;
- goto bail;
- }
-
- /*
- * See of we have a clip
- */
- SRPointList_ClipTestVertices(
- deviceVertices,
- clipFlags,
- numVertices,
- &srPrivate->clipPlanesInDC[0],
- &clipFound,
- &allOut,
- sizeof(TQ3RationalPoint4D));
-
- if (allOut) {
- /*
- * Return now, as nothing need be drawn
- */
- goto bail;
- }
-
- if (clipFound) {
- long numberOfClippedVertices;
-
- /*
- * Allocate space for clipped vertices. There will be at most
- * twice as many of these as there are in the original geometric
- * primitive. Bail if allocation fails.
- */
- clippedVertices =
- malloc((numVertices << 1) * sizeof(TQ3RationalPoint4D));
- if (clippedVertices == NULL) {
- free(deviceVertices);
- free(clipFlags);
- return (kQ3Failure);
- }
-
- /*
- * Allocate space for clip flags for vertices. Bail if allocation
- * fails.
- */
- clippedVerticesFlags =
- malloc((numVertices << 1) * sizeof(long));
- if (clippedVerticesFlags == NULL) {
- free(clippedVertices);
- free(deviceVertices);
- free(clipFlags);
- return (kQ3Failure);
- }
-
- SRPointList_ClipVertices(
- deviceVertices,
- sizeof(TQ3RationalPoint4D),
- clippedVertices,
- sizeof(TQ3RationalPoint4D),
- clipFlags,
- clippedVerticesFlags,
- numVertices,
- &numberOfClippedVertices,
- &srPrivate->clipPlanesInDC[0],
- mode);
-
- if (numberOfClippedVertices == 0) {
- goto bail;
- }
-
- renderVertices = clippedVertices;
- numVertices = numberOfClippedVertices;
- }
-
- /*
- * Divide by homogeneous coordinate
- */
- SRPointList_WDivide(
- renderVertices,
- numVertices,
- sizeof(TQ3RationalPoint4D));
-
- /*
- * Draw each of the points
- */
- for (i = 0; i < numVertices; i++) {
- if (!clipFound ||
- (clippedVerticesFlags &&
- clippedVerticesFlags[i] & SR_DRAW_NEXT)) {
- if ((*pointFunction)(
- srPrivate,
- (TQ3Point3D *)&renderVertices[i],
- color) == kQ3Failure) {
- return (kQ3Failure);
- }
- }
- }
-
- bail:
- /*
- * Free up any allocated memory
- */
- if (deviceVertices != NULL) {
- free(deviceVertices);
- }
-
- if (clipFlags != NULL) {
- free(clipFlags);
- }
-
- if (clippedVertices != NULL) {
- free(clippedVertices);
- }
-
- if (clippedVerticesFlags != NULL) {
- free(clippedVerticesFlags);
- }
-
- /*
- * Status may be success or failure, the latter being the case if
- * an allocation failed or if the line rasterization function returns
- * failure.
- */
- return (status);
- }
-